package com.kris;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 代表一个员工所有的出勤信息 是excel数据和处理对象之间的转换模型类。
 *
 * @author zhangqunshi
 */
class EmployeeAttendRecord {

    // 员工姓名
    private final String name;

    // 员工打卡日期, 打卡时间。 Key为不带时间的日期，用于定位哪一天(yyyyMMdd)
    private final Map<String, OneWorkingDay> timeMap = new HashMap<String, OneWorkingDay>();

    EmployeeAttendRecord(String employeeName) {
        this.name = employeeName;
    }

    // 一天工作时间
    class OneWorkingDay {

        Date beginTime;
        Date endTime;

        /**
         * 取最早的开始时间和最晚的结束时间。
         *
         * @param time
         */
        void add(Date time) {
            if (beginTime == null && endTime == null) {
                beginTime = time;
                endTime = time;
                return;
            }
            if (time.before(beginTime)) {
                beginTime = time;
            }
            if (time.after(endTime)) {
                endTime = time;
            }
        }
    }

    static final String DATE_FORMATE = "yyyy/MM/dd HH:mm:ss";

    /**
     * 把excel中的数据转成EmployeeAttendRecord对象。
     * EmployeeAttendRecord对象实际上代表了一个员工所有的考勤信息。
     *
     * @param rows 一个行记录的集合
     * @return
     */
    static Map<String, EmployeeAttendRecord> valueFrom(List<ExcelRow> rows)
            throws ParseException {
        Map<String, EmployeeAttendRecord> employeeMap
                = new HashMap<String, EmployeeAttendRecord>();
        for (ExcelRow row : rows) {
            // 获取checktime列的数据
            String checkTimeStr = row.getColumnValue(2);
            if (DateUtil.isNotDateType(checkTimeStr, DATE_FORMATE)) {
                // 忽略不是日期类型的数据
                continue;
            }
            Date checkTime = DateUtil.convert(checkTimeStr,
                    DATE_FORMATE);
            // 获取name列的数据
            String name = row.getColumnValue(10);

            // 忽略表头
            if ("name".equals(name)) {
                continue;
            }

            if (employeeMap.containsKey(name)) {
                EmployeeAttendRecord ear = employeeMap.get(name);
                ear.add(checkTime);
            } else {
                EmployeeAttendRecord ear = new EmployeeAttendRecord(name);
                ear.add(checkTime);
                employeeMap.put(name, ear);
            }
        }

        return employeeMap;
    }

    /**
     * 一个员工所有上班记录的集合
     *
     * @return
     */
    List<EmployeeWorkTime> getWorkTimeRecords() throws ParseException {
        List<EmployeeWorkTime> timeList = new ArrayList<EmployeeWorkTime>();
        for (String key : timeMap.keySet()) {
            OneWorkingDay day = timeMap.get(key);
            EmployeeWorkTime workTime = new EmployeeWorkTime();
            workTime.setName(this.name);
            workTime.setWorkDate(day.beginTime);
            workTime.setBeginTime(day.beginTime);
            workTime.setEndTime(day.endTime);

            timeList.add(workTime);
        }

        return timeList;
    }

    final String KEY_datePattern = "yyyyMMdd";

    private void add(Date checkTime) {
        String day = DateUtil.onlyGetDate(checkTime, KEY_datePattern);
        if (this.timeMap.containsKey(day)) {
            OneWorkingDay oneDay = this.timeMap.get(day);
            oneDay.add(checkTime);
        } else {
            OneWorkingDay oneDay = new OneWorkingDay();
            oneDay.add(checkTime);
            this.timeMap.put(day, oneDay);
        }
    }

    /**
     * 计算员工第一天打卡的日期（用于倒休统计报表）
     *
     * @return
     * @throws ParseException
     */
    public Date getFirstDay() throws ParseException {
        Date firstDay = null;
        for (String key : this.timeMap.keySet()) {
            Date d = DateUtil.parse(key, KEY_datePattern);
            if (firstDay == null) {
                firstDay = d;
                continue;
            }
            if (d.before(firstDay)) {
                firstDay = d;
            }
        }
        return firstDay;
    }

    /**
     * 计算员工最后一天打卡的日期（用于倒休统计报表）
     *
     * @return
     * @throws ParseException
     */
    public Date getLastDay() throws ParseException {
        Date lastDay = null;
        for (String key : this.timeMap.keySet()) {
            Date d = DateUtil.parse(key, KEY_datePattern);
            if (lastDay == null) {
                lastDay = d;
                continue;
            }
            if (d.after(lastDay)) {
                lastDay = d;
            }
        }
        return lastDay;
    }

}
